package com.mzj.saas.sdk.pay.callback;


import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.XmlUtil;
import com.mzj.saas.sdk.util.WechatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.util.HashMap;
import java.util.Map;

public class WxPayCallback extends AbstractPayCallback{

	private final static Logger logger = LoggerFactory.getLogger(WxPayCallback.class);

	private String mchApiKey;

	private HttpServletRequest request;

	private HttpServletResponse response;

	private Map<String, Object> resultMap;


	public WxPayCallback(String mchApiKey,HttpServletRequest request,HttpServletResponse response) {
		this.mchApiKey = mchApiKey;
		this.request = request;
		this.response = response;
	}

	@Override
	protected String key() {
		// TODO Auto-generated method stub
		return mchApiKey;
	}

	/**
	 * 数据解析
	 * https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3
	 * return null错误 ,返回相关数据
	 */
	@Override
	public Map<String, String> verifyResult() {
		// TODO Auto-generated method stub
		try {
			BufferedReader bufferedReader = IoUtil.getUtf8Reader(request.getInputStream());
			String xmlBody = IoUtil.read(bufferedReader);
			resultMap = XmlUtil.xmlToMap(xmlBody);
			if (resultMap == null || resultMap.isEmpty()) {
				logger.error("verifySignature---> 微信支付结果回调通知-数据解析为空！xmlBody=[{}]", xmlBody);
				return null;
			}
			String returnCode = StrUtil.utf8Str(resultMap.get("return_code")); // 返回状态码
			String returnMsg = StrUtil.utf8Str(resultMap.get("return_msg")); // 返回信息
			String resultCode = StrUtil.utf8Str(resultMap.get("result_code")); // 业务结果
			String errCode = StrUtil.utf8Str(resultMap.get("err_code")); // 错误代码
			String errCodeDes = StrUtil.utf8Str(resultMap.get("err_code_des")); // 错误代码描述
			if (!"SUCCESS".equals(returnCode) || !"SUCCESS".equals(resultCode)) {
				logger.error("verifySignature---> 微信支付结果回调通知-支付结果为失败！[returnCode={}，returnMsg={}，resultCode={}，errCode={}，errCodeDes={}]", returnCode, returnMsg, resultCode, errCode, errCodeDes);
				return null;
			}

			//签名验证
			if(mchApiKey != null && !WechatUtils.signCheck(resultMap, mchApiKey)) {
				logger.error("verifySignature---> 微信支付结果回调通知-签名验证不通过！resultMap=[{}]", resultMap);
				return null;
			}

			String appid = StrUtil.utf8Str(resultMap.get("appid"));
			String mchId = StrUtil.utf8Str(resultMap.get("mch_id"));
			String nonceStr = StrUtil.utf8Str(resultMap.get("nonce_str"));
			String totalFee = StrUtil.toString(resultMap.get("total_fee")); // 订单总金额
			String transactionId = StrUtil.toString(resultMap.get("transaction_id")); // 微信支付订单号
			String outTradeNo = StrUtil.toString(resultMap.get("out_trade_no")); // 商户订单号
			String attach = StrUtil.toString(resultMap.get("attach")); // 自定义参数
			String timeEnd = StrUtil.toString(resultMap.get("time_end"));

			Map<String, String> result = new HashMap<String, String>();
			result.put("totalFee", totalFee);
			result.put("transactionId", transactionId);
			result.put("outTradeNo", outTradeNo);
			result.put("attach", attach);
			result.put("returnCode", returnCode);
			result.put("returnMsg", returnMsg);
			result.put("resultCode", resultCode);
			result.put("errCode", errCode);
			result.put("errCodeDes", errCodeDes);
			result.put("appid", appid);
			result.put("mchId", mchId);
			result.put("nonceStr", nonceStr);
			result.put("timeEnd", timeEnd);
			return result;
		}catch(Exception e) {
			logger.error("微信支付结果回调通知-处理异常", e);
		}
		return null;
	}

	@Override
	protected Map<String, String> getReqInfo(Map<String, String> packageParams) {
		return null;
	}

	@Override
	public boolean verifySignature(String... values) {

		if(resultMap == null) {
			logger.error("verifySignature---> 微信支付结果回调通知-签名验证不通过！resultMap=[{}]", resultMap);
			return false;
		}

		boolean signCheck = WechatUtils.signCheck(resultMap, values[0]);
		if (!signCheck) {
			logger.error("verifySignature---> 微信支付结果回调通知-签名验证不通过！resultMap=[{}]", resultMap);
			return false;
		}
		return true;
	}


	/**
	 * 返回成功消息
	 */
	@Override
	public void resultSuccess() throws Exception{
		StringBuffer buffer = new StringBuffer();
		buffer //
				.append("<xml>") //
				.append("<return_code><![CDATA[").append(WechatUtils.SUCCESS).append("]]></return_code>") //
				.append("<return_msg><![CDATA[").append("OK").append("]]></return_msg>") //
				.append("</xml>");
		response.setContentType("text/xml");
		BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
		out.write(buffer.toString().getBytes());
		out.flush();
		out.close();
	}


	/**
	 * 返回失败消息
	 */
	@Override
	public void resultFail() throws Exception{
		StringBuffer buffer = new StringBuffer();
		buffer //
				.append("<xml>") //
				.append("<return_code><![CDATA[").append(WechatUtils.FAIL).append("]]></return_code>") //
				.append("<return_msg><![CDATA[").append("失败").append("]]></return_msg>") //
				.append("</xml>");
		response.setContentType("text/xml");
		BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
		out.write(buffer.toString().getBytes());
		out.flush();
		out.close();
	}
}
